<?php

namespace app\data\service;

use think\admin\Service;

/**
 * 日报
 * Class DailyOutputService
 * @package app\data\service
 */
class DailyOutputService extends Service
{
    public function formatDate($date, $maxTime)
    {
        // 获取城市师傅树
        $cityRelations = CityUserRelationService::instance()->getCityUserTree();
        foreach ($cityRelations as $cityRelation) {
            $hasProvinces[$cityRelation['from_province'] . $cityRelation['from_city']] = 1;
        }
        $cityRelations = array_merge($cityRelations, [[
            'id' => 0,
            'users' => [],
            'from_province' => '',
            'from_city' => '',
        ]]);

        // 获取所有城市
        $allProvinces = $this->app->db->name('data_record')
            ->where('time_docking', '<=', $maxTime)
            ->field('DISTINCT province, city')
            ->select();

        $mergeProvinces[] = '##';
        foreach ($allProvinces as $allProvince) {
            if (!isset($hasProvinces[$allProvince['province'] . $allProvince['city']])) {
                $mergeProvinces[] = $allProvince['province'] . '##' . $allProvince['city'];
            }
        }

        // 查询企业微信打卡信息
        $checkInUsers = CityUserRelationService::instance()->checkInUsers($cityRelations, strtotime($date), strtotime($maxTime));

        // 采集到的派单数据
        $records = $this->app->db->name('data_record')
            ->where('time_docking', '>=', $date)
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $province2Ids['##'][] = $record['id'];
            } else {
                $province2Ids[$address][] = $record['id'];
            }
        }

        // 已经完成的订单
        $records = $this->app->db->name('data_record')
            ->where('paint_status', 1)
            ->where('time_complete', '>=', $date)
            ->where('time_complete', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $completeProvince2Ids['##'][] = $record['id'];
            } else {
                $completeProvince2Ids[$address][] = $record['id'];
            }
        }

        // 当日派单日期且当前施工完成的派单数据
        $records = $this->app->db->name('data_record')
            ->where('paint_status', 1)
            ->where('time_docking', '>=', $date)
            ->where('time_docking', '<=', $maxTime)
            ->where('time_complete', '>=', $date)
            ->where('time_complete', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $todayProvince2Ids['##'][] = $record['id'];
            } else {
                $todayProvince2Ids[$address][] = $record['id'];
            }
        }

        // 总未完工数(当前城市归属中所有未完工工单数量)
        $records = $this->app->db->name('data_record')
            ->whereIn('paint_status', [0, -1])
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $notCompleteProvince2Ids['##'][] = $record['id'];
            } else {
                $notCompleteProvince2Ids[$address][] = $record['id'];
            }
        }

        // 派单总数(已派单的所有数据)
        $records = $this->app->db->name('data_record')
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $allRecordProvince2Ids['##'][] = $record['id'];
            } else {
                $allRecordProvince2Ids[$address][] = $record['id'];
            }
        }

        // 总完工数(已喷漆完成所有的所有数据)
        $records = $this->app->db->name('data_record')
            ->where('paint_status', 1)
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $allCompleteProvince2Ids['##'][] = $record['id'];
            } else {
                $allCompleteProvince2Ids[$address][] = $record['id'];
            }
        }

        // 未完工数(当前筛选日期中,未完工的工单数量)
        $records = $this->app->db->name('data_record')
            ->whereIn('paint_status', [0, -1])
            ->where('time_docking', '>=', $date)
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $todayNotCompleteProvince2Ids['##'][] = $record['id'];
            } else {
                $todayNotCompleteProvince2Ids[$address][] = $record['id'];
            }
        }

        // 未喷漆的派单数据
        $records = $this->app->db->name('data_record')
            ->whereIn('paint_status', [-1, 0])
            ->where('time_docking', '>=', $date)
            ->where('time_docking', '<=', $maxTime)
            ->select()->toArray();
        foreach ($records as $record) {
            $address = $record['province'] . '##' . $record['city'];
            if (in_array($address, $mergeProvinces ?? [])) {
                $cancelOrderDetail['##'][] = [
                    'id' => $record['id'],
                    'plate_number' => $record['plate_number'],
                    'invite_remark' => $record['invite_remark'],
                    'invite_remarks' => $record['invite_remarks'],
                ];
            } else {
                $cancelOrderDetail[$address][] = [
                    'id' => $record['id'],
                    'plate_number' => $record['plate_number'],
                    'invite_remark' => $record['invite_remark'],
                    'invite_remarks' => $record['invite_remarks'],
                ];
            }
        }

        // 默认组均能效
        $defaultEnergy = sysconf('data.default_energy');

        foreach ($cityRelations as $cityRelation) {

            // 实到组数(现有组人力)
            $realGroupPower = 0;
            foreach ($cityRelation['users'] ?? [] as $user) {
                if (in_array($user['user_id'], $checkInUsers)) {
                    $realGroupPower ++;
                }
            }
//            $realGroupPower = count($cityRelation['users'] ?? []);


            $address = $cityRelation['from_province'] . '##' . $cityRelation['from_city'];

            // 总产出(当前时间内施工完成的数量)
            $completeCount = count($completeProvince2Ids[$address] ?? []);

            // 产出(当日派单日期且当前施工完成数量)
            $completeTodayCount = count($todayProvince2Ids[$address] ?? []);

            // 总未完工数(当前城市归属中所有未完工工单数量)
            $notCompleteCount = count($notCompleteProvince2Ids[$address] ?? []);

            // 派单总数(已派单的所有数据)
            $allRecordCount = count($allRecordProvince2Ids[$address] ?? []);

            // 总完工数(已喷漆完成所有的所有数据)
            $allCompleteCount = count($allCompleteProvince2Ids[$address] ?? []);

            // 未完工数(当前筛选日期中,未完工的工单数量)
            $notCompleteTodayCount = count($todayNotCompleteProvince2Ids[$address] ?? []);

            // 日均去化能力=现有组人力*组均能效
            $groupEnergy = bcmul($realGroupPower, $defaultEnergy, 0);

            // 日均差异=产出-日均去化能力
            $diff = $completeTodayCount - $groupEnergy;

            // 派单数
            $recordCount = count($province2Ids[$address] ?? []);

            // 总差异=产出时间-日均去化能力
            $countDiff = $completeCount - $groupEnergy;

            // 实际差异数=派单数-总产出数
            $realDiff = $recordCount - $completeCount;

            $insertData[] = [
                'date' => $date,
                'city_relation_id' => $cityRelation['id'],
                'from_province' => $cityRelation['from_province'],
                'from_city' => $cityRelation['from_city'],
                'people_power' => $realGroupPower, // 现有人力
                'group_power' => count($cityRelation['users']), // 应到组数
                'complete_count' => $completeCount, // 总产出(当前时间内施工完成的数量)
                'complete_today_count' => $completeTodayCount, // 产出(当日派单日期且当前施工完成数量)
                'not_complete_count' => $notCompleteCount, // 总未完工数(当前城市归属中所有未完工工单数量)
                'not_complete_today_count' => $notCompleteTodayCount, // 未完工数(当前筛选日期中,未完工的工单数量)
                'group_energy' => $groupEnergy, // 日均去化能力=现有组人力*组均能效
                'diff' => $diff, // 日均差异=产出-日均去化能力
                'count_diff' => $countDiff, // 总差异=产出时间-日均去化能力
                'real_diff' => $realDiff, // 实际差异数=派单数-产出数
                'record_count' => $recordCount, // 派单=运满满派单采集到的派单数据
                'all_record_count' => $allRecordCount, // 派单总数(已派单的所有数据)
                'all_complete_count' => $allCompleteCount, // 总完工数(已喷漆完成所有的所有数据)
                'real_group_power' => $realGroupPower, // 实到组数(现有组人力)
                'energy' => $defaultEnergy, // 组均能效
                'cancel_order_json' => $this->formatOrderJson($cancelOrderDetail[$address] ?? []), // 取消的订单ID跟原因
            ];
        }

        if (!empty($insertData)) {
            $this->app->db->name('report_daily_output')->insertAll($insertData);
            unset($insertData);
        }
    }

    /**
     * 格式化未做原因
     * @param $cancelOrderDetail
     * @return mixed
     */
    private function formatOrderJson($cancelOrderDetail)
    {
        foreach ($cancelOrderDetail as &$item) {
            $remark = [];
            if (!empty($item['invite_remark'])) {
                $remark = [$item['invite_remark']];
            }
            if (!empty($item['invite_remarks'])) {
                if (empty($remark)) {
                    $remark = explode(PHP_EOL, $item['invite_remarks']);
                } else {
                    $remark = array_merge($remark, explode(PHP_EOL, $item['invite_remarks']));
                }
            }

            $item['remark'] = $item['plate_number'] . ' ' . implode('。', $remark);
        }

        return json_encode($cancelOrderDetail);
    }
}